package com.qiyi.player.core.video.file.clientp2pfile
{
   import flash.events.EventDispatcher;
   import com.qiyi.player.core.player.coreplayer.ICorePlayer;
   import com.qiyi.player.core.model.IMovie;
   import com.qiyi.player.core.video.decoder.IDecoder;
   import com.qiyi.player.core.video.provider.actors.clientp2p.ClientP2PEngine;
   import com.qiyi.player.core.video.file.actors.datatile.IFlvBlock;
   import com.qiyi.player.base.logging.ILogger;
   import com.qiyi.player.core.model.impls.Definition;
   import com.qiyi.player.core.model.impls.Segment;
   import com.qiyi.player.core.video.file.actors.datatile.MediaData;
   import com.qiyi.player.core.video.file.actors.MediaUtils;
   import com.qiyi.player.core.model.impls.Keyframe;
   import com.qiyi.player.base.logging.Log;
   
   public class ClientP2PFile extends EventDispatcher implements IClientP2PFile
   {
      
      public function ClientP2PFile() {
         this._log = Log.getLogger("com.qiyi.player.core.video.file.clientp2pfile.ClientP2PFile");
         super();
         this._blocks = new Vector.<IFlvBlock>();
         this._log.debug("ClientP2PFile has been created!");
      }
      
      private var _holder:ICorePlayer;
      
      private var _movie:IMovie;
      
      private var _decoder:IDecoder;
      
      private var _clientP2PEngine:ClientP2PEngine;
      
      private var _blocks:Vector.<IFlvBlock>;
      
      private var _readingIndex:int = -1;
      
      private var _seeked:Boolean = false;
      
      private var _log:ILogger;
      
      public function get holder() : ICorePlayer {
         return this._holder;
      }
      
      public function get movie() : IMovie {
         return this._movie;
      }
      
      public function get bufferLength() : int {
         return this._clientP2PEngine.bufferTime;
      }
      
      public function get eof() : Boolean {
         if(this._blocks.length == 0)
         {
            return false;
         }
         var _loc1_:int = this._blocks.length - 1;
         if(this._readingIndex != _loc1_)
         {
            return false;
         }
         var _loc2_:Definition = this._movie.curDefinition;
         if(_loc2_ == null)
         {
            return true;
         }
         var _loc3_:Segment = _loc2_.findSegmentAt(_loc2_.segmentCount - 1);
         var _loc4_:int = this._holder.runtimeData.endTime;
         if(_loc4_ == 0 && (this._holder.runtimeData.skipTrailer))
         {
            _loc4_ = this._movie.trailerTime;
         }
         if(_loc4_ > 0 && this._blocks[_loc1_].segment.endTime >= _loc4_)
         {
            return this._blocks[_loc1_].eof;
         }
         if(this._blocks[_loc1_].segment != _loc3_)
         {
            return false;
         }
         if(!this._blocks[_loc1_].eof)
         {
            return false;
         }
         return Math.abs(this._blocks[_loc1_].endTime - _loc3_.endTime) < 5000;
      }
      
      public function get blockCount() : int {
         return this._blocks.length;
      }
      
      public function get readingIndex() : int {
         return this._readingIndex;
      }
      
      public function initialize(param1:ICorePlayer, param2:IMovie, param3:IDecoder) : void {
         this._holder = param1;
         this._movie = param2;
         this._decoder = param3;
         this._clientP2PEngine = this._holder.clientP2PEngine;
      }
      
      public function addBlock(param1:IFlvBlock) : int {
         var _loc2_:* = 0;
         var _loc3_:* = 0;
         var _loc4_:int = param1.startTime;
         _loc2_ = 0;
         _loc3_ = this._blocks.length;
         while(_loc2_ < _loc3_)
         {
            if(_loc4_ < this._blocks[_loc2_].startTime)
            {
               break;
            }
            _loc2_++;
         }
         this._blocks.splice(_loc2_,0,param1);
         if(this._blocks.length == 1)
         {
            this._readingIndex = 0;
         }
         else if(this._readingIndex >= 0 && _loc2_ <= this._readingIndex)
         {
            this._readingIndex++;
         }
         
         this._log.debug("ClientP2PFile add block:" + _loc2_ + ", startPosition:" + param1.startPosition + ", endPosition:" + param1.endPosition + ", readingIndex:" + this._readingIndex + ", blockId:" + param1.id);
         return _loc2_;
      }
      
      public function removeBlock(param1:IFlvBlock) : int {
         var _loc4_:IFlvBlock = null;
         var _loc5_:* = 0;
         var _loc6_:* = 0;
         var _loc7_:Segment = null;
         var _loc2_:* = 0;
         var _loc3_:int = this._blocks.length;
         while(_loc2_ < _loc3_)
         {
            if(this._blocks[_loc2_] == param1)
            {
               _loc4_ = this._blocks[_loc2_];
               _loc5_ = _loc4_.startPosition;
               _loc6_ = _loc4_.endPosition;
               _loc7_ = _loc4_.segment;
               _loc4_.destroy();
               this._blocks.splice(_loc2_,1);
               if(this._readingIndex != -1)
               {
                  if(_loc2_ == this._readingIndex)
                  {
                     this._readingIndex = -1;
                  }
                  else if(_loc2_ < this._readingIndex && this._readingIndex >= 0)
                  {
                     this._readingIndex--;
                  }
                  
               }
               this._log.debug("ClientP2PFile remove block:" + _loc2_ + ", startPosition:" + _loc5_ + ", endPosition:" + _loc6_ + ", readingIndex:" + this._readingIndex + ", blockId:" + param1.id);
               return _loc2_;
            }
            _loc2_++;
         }
         return -1;
      }
      
      public function removeBlockAt(param1:int) : void {
         var _loc2_:IFlvBlock = null;
         var _loc3_:* = 0;
         var _loc4_:Segment = null;
         if(param1 >= 0 && param1 < this._blocks.length)
         {
            _loc2_ = this._blocks[param1];
            _loc3_ = _loc2_.startPosition;
            _loc4_ = _loc2_.segment;
            _loc2_.destroy();
            this._blocks.splice(param1,1);
            if(this._readingIndex != -1)
            {
               if(param1 == this._readingIndex)
               {
                  this._readingIndex = -1;
               }
               else if(param1 < this._readingIndex && this._readingIndex >= 0)
               {
                  this._readingIndex--;
               }
               
            }
            this._log.debug("ClientP2PFile remove block: " + param1 + ", current: " + this._readingIndex + ",blockId:" + _loc2_.id);
         }
      }
      
      public function findBlockAt(param1:int) : IFlvBlock {
         if(param1 >= 0 && param1 < this._blocks.length)
         {
            return this._blocks[param1];
         }
         return null;
      }
      
      public function findBlockIndexFrom(param1:Segment, param2:int) : int {
         var _loc3_:* = -1;
         var _loc4_:* = 0;
         var _loc5_:int = this._blocks.length;
         while(_loc4_ < _loc5_)
         {
            if(this._blocks[_loc4_].segment == param1)
            {
               if(this._blocks[_loc4_].startPosition <= param2 && param2 < this._blocks[_loc4_].endPosition)
               {
                  _loc3_ = _loc4_;
                  break;
               }
               if(this._blocks[_loc4_].startPosition == this._blocks[_loc4_].endPosition && param2 == this._blocks[_loc4_].startPosition)
               {
                  _loc3_ = _loc4_;
                  break;
               }
            }
            _loc4_++;
         }
         return _loc3_;
      }
      
      public function sequenceReadData() : MediaData {
         if(this._readingIndex == -1)
         {
            return null;
         }
         var _loc1_:IFlvBlock = this._blocks[this._readingIndex];
         var _loc2_:MediaData = _loc1_.read();
         if(_loc2_ == null)
         {
            if((_loc1_.eof) && this._blocks.length > this._readingIndex + 1)
            {
               this._blocks[++this._readingIndex].reset();
               if(this._blocks[this._readingIndex].mediaSize > 0)
               {
                  this._log.info("ClientP2PFile switch to next block:" + this._blocks[this._readingIndex].segment.index);
                  if(!(this._blocks[this._readingIndex - 1].segment == this._blocks[this._readingIndex].segment) && !MediaUtils.verifyFlvBlockHeaderConfigIsSame(this._blocks[this._readingIndex - 1],this._blocks[this._readingIndex]))
                  {
                     this._log.info("ClientP2PFile sequenceReadData , get flv header");
                     _loc2_ = new MediaData();
                     _loc2_.headers = this._blocks[this._readingIndex].getHeaders();
                  }
               }
               else
               {
                  this._log.debug("ClientP2PFile waiting data of the next block!");
               }
               do
               {
                  this.removeBlockAt(0);
               }
               while(this._readingIndex != 0);
               
            }
         }
         else if(this._seeked)
         {
            this._seeked = false;
            _loc2_.headers = _loc1_.getHeaders();
         }
         
         return _loc2_;
      }
      
      public function sequenceReadDataFrom(param1:int) : MediaData {
         return null;
      }
      
      public function seek(param1:int) : void {
         var _loc6_:* = 0;
         var _loc7_:* = 0;
         this._log.info("ClientP2PFile seeking: " + param1);
         this._seeked = true;
         if(this._readingIndex >= 0)
         {
            this._blocks[this._readingIndex].reset();
         }
         var _loc2_:* = 0;
         var _loc3_:Segment = this._movie.getSegmentByTime(param1);
         var _loc4_:Keyframe = _loc3_.getKeyframeByTime(param1);
         if(_loc4_)
         {
            _loc2_ = _loc4_.position;
         }
         var _loc5_:int = this.findBlockIndexFrom(_loc3_,_loc2_);
         if(_loc5_ == -1)
         {
            _loc6_ = this._blocks.length;
            _loc7_ = 0;
            while(_loc7_ < _loc6_)
            {
               this._blocks[_loc7_].destroy();
               _loc7_++;
            }
            this._blocks = new Vector.<IFlvBlock>();
            this._readingIndex = -1;
         }
         else
         {
            this._readingIndex = _loc5_;
            this._blocks[_loc5_].seek(param1);
         }
      }
      
      public function clear() : void {
         var _loc1_:int = this._blocks.length;
         var _loc2_:* = 0;
         while(_loc2_ < _loc1_)
         {
            this._blocks[_loc2_].destroy();
            _loc2_++;
         }
         this._blocks = new Vector.<IFlvBlock>();
         this._readingIndex = -1;
         this._seeked = false;
      }
      
      public function prepareSwitchMediaData() : void {
         var _loc1_:int = this._blocks.length;
         var _loc2_:* = 0;
         while(_loc2_ < _loc1_)
         {
            this._blocks[_loc2_].destroy();
            _loc2_++;
         }
         this._blocks = new Vector.<IFlvBlock>();
         this._readingIndex = -1;
      }
      
      public function destroy() : void {
         var _loc1_:* = 0;
         var _loc2_:* = 0;
         if(this._blocks)
         {
            _loc1_ = this._blocks.length;
            _loc2_ = 0;
            while(_loc2_ < _loc1_)
            {
               this._blocks[_loc2_].destroy();
               _loc2_++;
            }
            this._blocks = null;
         }
         this._movie = null;
         this._readingIndex = -1;
      }
   }
}
